package com.kitty.game.equip.handler;

import com.kitty.game.role.model.Role;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.model.RoleEquipField;
import com.kitty.game.attribute.config.Attribute;
import com.kitty.game.config.Equip;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.equip.EquipDataPool;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.utils.AsktaoUtil;
import com.kitty.mina.message.MessagePusher;
import lombok.extern.slf4j.Slf4j;
import org.nutz.json.Json;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;
import com.kitty.game.equip.handler.UpgradeHandler;

import static com.kitty.game.utils.Const.*;
import static com.kitty.game.utils.NotifyModules.NOTIFY_EQUIP_REFINE_OK;

/**
 * 炼化属性继承类
 */
@Component
@Slf4j
public abstract class RefineHandler extends UpgradeHandler {

    private static final String PRE_MESSAGE = "你消耗了1枚#R{0}#n进行炼化属性预览。";
    /**
     * 炼化成功提示
     */
    private static final String REFINE_SUCCESS = "恭喜你，花费了{0}文钱，炼化成功，属性已重新生成。";
    /**
     * 炼化失败提示
     */
    private static final String REFINE_FAIL = "真遗憾，炼化失败了。";
    /**
     * 武器炼化会出现的属性列表
     */
    private static final List<Integer> WEAPON_FIELDS = EquipService.Weapons;
    /**
     * 头盔炼化会出现的属性列表
     */
    private static final List<Integer> HELMET_FIELDS = EquipService.Hats;
    /**
     * 衣服炼化会出现的属性列表
     */
    private static final List<Integer> ARMOR_FIELDS = EquipService.Clothes;
    /**
     * 鞋子炼化会出现的属性列表
     */
    private static final List<Integer> BOOT_FIELDS = EquipService.Shoes;

    public abstract Short getDiffField();

    public abstract short getPreField();

    public abstract short getField();

    public abstract short getSuitField();

    public abstract short getPreSuitField();

    public abstract String getBeforeColor();

    public abstract String getThisColor();

    public abstract String getOperStr();

    public abstract String getCrystal();

    @Override
    public String doUpgrade(Role role, Object... params) {
        RoleEquip roleEquip = (RoleEquip) params[0];
        String param = (String) params[1];
        Equip equip = (Equip) params[2];

        String[] split = param.split("\\|");
        boolean isUseLimit, opType;
        int size = 1;
        int polor = 0;
        boolean success = true;
        Random random = new Random();
        if (getUpdateTypeStr().equals("gold_refine")) {
            size = Integer.parseInt(split[1]);
            isUseLimit = split[0].equals("1");
            opType = split[2].equals("1");
            if (size == 3) {//3 40 4 55 5 70 6 100
                int result = random.nextInt(100);
                if (result >= 40) {
                    success = false;// 失败
                }
            } else if (size == 4) {
                int result = random.nextInt(100);
                if (result >= 55) {
                    success = false;// 失败
                }
            } else if (size == 5) {
                int result = random.nextInt(100);
                if (result >= 70) {
                    success = false;// 失败
                }
            }
        } else if (getUpdateTypeStr().equals("suit_refine")) {
            polor = Integer.parseInt(split[1]);
            isUseLimit = split[0].equals("1");
            opType = split[2].equals("1");
        } else {
            isUseLimit = split[0].equals("1");
            opType = split[1].equals("1");
        }

        /**扣钱*/
        int cash = needCash(roleEquip.queryLevel(), 0);
        roleService.subtractMoney(role, cash);
        int limitNum = 0;
        /**删除道具*/
        limitNum += equipService.delRoloEquip(getCrystal(), size, isUseLimit, role);
        if (opType) {
            limitNum += equipService.delRoloEquip(getGemName(roleEquip.queryLevel()), 1, true, role);
        }

        /**添加限制时间*/
        if (limitNum >= 1) {
            roleEquip.addLimitTime(limitNum);
        }
        if (success) {
            /**获得随机属性*/
            int fieldId;
            int pos = roleEquip.queryEquipPos(false);
            if (getUpdateTypeStr().equals("suit_refine")) {
                int equipPolar = 0;
                if (pos == WEAPON) {
                    equipPolar = equip.getMenpai();
                } else {
                    equipPolar = polor;
                }
                fieldId = getRandomField(pos, roleEquip, equipPolar);
            } else {
                fieldId = getRandomField(pos, roleEquip, 0);
            }

            int operField = 0;
            int fixedField = 0;
            if (opType) {
                /**删除原来的替换属性*/
                roleEquip.getFields().remove(getPreField());
                operField = getPreField();
                /**套装有2条属性 所以要删除2条*/
                if (getUpdateTypeStr().equals("suit_refine")) {
                    roleEquip.getFields().remove(getPreSuitField());
                    fixedField = getPreSuitField();
                }
                RespNotifyMiscEx respNotifyMiscEx = new RespNotifyMiscEx();
                respNotifyMiscEx.setMsg(MessageFormat.format(PRE_MESSAGE, getGemName(roleEquip.queryLevel())));
                respNotifyMiscEx.setTime(new Long(System.currentTimeMillis() / 1000).intValue());
                MessagePusher.pushMessage(role, respNotifyMiscEx);
            } else {
                /**删除原来的属性*/
                roleEquip.getFields().remove(getField());
                operField = getField();
                /**套装有2条属性 所以要删除2条*/
                if (getUpdateTypeStr().equals("suit_refine")) {
                    roleEquip.getFields().remove(getSuitField());
                    fixedField = getSuitField();
                }
            }

            /**修改装备颜色 是蓝色就修改成 粉色*/
            if (roleEquip.queryColor().equals(getBeforeColor())) {
                roleEquip.alterColor(getThisColor());
            }

            /**添加随机的属性*/
            addNewField(operField, fieldId, roleEquip, equip);

            /**如果是绿装备 还要添加一个固定属性 根据相性添加*/
            if (getUpdateTypeStr().equals("suit_refine")) {
                addSuitFixedField(fixedField, roleEquip, equip, polor);
            }

            refreshRoleEquip(role, roleEquip);
            equipService.countPerfect(roleEquip);
            pushOperateResult(role, UPGRADE_SUCCESS);

            return MessageFormat.format(REFINE_SUCCESS, AsktaoUtil.getMoneyFormat(cash));
        } else {
            pushOperateResult(role, UPGRADE_FAIL);
            return REFINE_FAIL;
        }

    }

    protected abstract void addSuitFixedField(int fixedField, RoleEquip roleEquip, Equip equip, int polor);

    private void addNewField(int operField, int fieldId, RoleEquip roleEquip, Equip equip) {
        RoleEquipField roleEquipField = new RoleEquipField();
        roleEquipField.setType((short) operField);
        roleEquipField.setField(new LinkedHashMap<>());
        FiedValue fiedValue = new FiedValue();
        fiedValue.setType((short) fieldId);
        Attribute attribute = attrService.getAttr(fieldId);
        fiedValue.setVT(attribute.getType());
        int min = attrService.getFiledMin(fiedValue.getType(), equip.getReq_level(), equip.getPosition());
        int max = attrService.getFiledMax(fiedValue.getType(), equip.getReq_level(), equip.getPosition());
        int value = new Random().nextInt(max - min) + min + 1;
        fiedValue.setValue(value);
        roleEquipField.getField().put(fiedValue.getType(), fiedValue);
//        logger.error("addNewField=={}", Json.toJson(roleEquipField));
        roleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
    }


    public abstract List<Integer> getSuitFieldId(int pos, int polar);

    /**
     * 获取一个随机的属性ID
     */
    private int getRandomField(int position, RoleEquip roleEquip, int polar) {
        int result = -1;
        Random random = new Random();
        while (true) {
            if (polar > 0) {
                List<Integer> fields = getSuitFieldId(position, polar);
                int index = random.nextInt(fields.size());
                result = fields.get(index);
            } else {
                if (position == 1) {
                    // 掉武器
                    int index = random.nextInt(WEAPON_FIELDS.size());
                    result = WEAPON_FIELDS.get(index);
                } else if (position == 2) {
                    // 帽子
                    int index = random.nextInt(HELMET_FIELDS.size());
                    result = HELMET_FIELDS.get(index);
                } else if (position == 3) {
                    // 衣服
                    int index = random.nextInt(ARMOR_FIELDS.size());
                    result = ARMOR_FIELDS.get(index);
                } else if (position == 10) {
                    // 鞋子
                    int index = random.nextInt(BOOT_FIELDS.size());
                    result = BOOT_FIELDS.get(index);
                }
            }

            short preFieldId = 0;
            if (getPreField() == 5890) {
                preFieldId = 6146;
            } else if (getPreField() == 6146) {
                preFieldId = 5890;
            }
            RoleEquipField roleEquipField = roleEquip.getFields().get(getDiffField());
            RoleEquipField preField = roleEquip.getFields().get(preFieldId);
            /**先判断不可重复属性段的预览属性里面有没有这个属性*/
            if (preField == null || preField.getField().get((short) result) == null) {
                if (roleEquipField == null || roleEquipField.getField().get((short) result) == null) {
                    break;
                }
            }
        }
        return result;
    }

    @Override
    public String acceptUpgrade(Role role, int upgradePos, String param) {
        RoleEquip roleEquip = equipService.getRoleEquipByPos(role, upgradePos);
        if (roleEquip == null) {
            return "请放入正确的装备。";
        }
        if (!isRightPosition(roleEquip.queryEquipPos(false))) {
            return MessageFormat.format(NO_RIGHT_POSITION, getOperStr(), roleEquip.getName());
        }
        Equip equip = EquipDataPool.getByName(roleEquip.getName());
        if (equip == null) {
            log.error("找不到装备配置ICON=[{}]", upgradePos);
            return MessageFormat.format(NOT_FIND_CONFIG, roleEquip.getName());
        }

        String noEnough = checkResource(role, param, roleEquip);
        if (noEnough != null) {
            return noEnough;
        }


        return doUpgrade(role, roleEquip, param, equip);
    }

    @Override
    public String checkResource(Object... objects) {
        Role role = (Role) objects[0];
        String param = (String) objects[1];
        RoleEquip roleEquip = (RoleEquip) objects[2];
        if (roleEquip.getType().equals("未鉴定装备")) {
            return MessageFormat.format(FAIL_MESSAGE, roleEquip.getName());
        }
        short level = roleEquip.queryLevel();

        String[] params = param.split("\\|");
        boolean isUseLimit;
        boolean opType;
        int size = 1;
        if (getUpdateTypeStr().equals("gold_refine")) {
            size = Integer.parseInt(params[1]);
            if (size < 3) {
                return "请最少放入3个或以上黄水晶。";
            }
            isUseLimit = params[0].equals("1");
            opType = params[2].equals("1");
            ;
        } else if (getUpdateTypeStr().equals("suit_refine")) {
            isUseLimit = params[0].equals("1");
            opType = params[2].equals("1");
            ;
        } else {
            isUseLimit = params[0].equals("1");
            opType = params[1].equals("1");
            ;
        }

        /**水晶*/
        int crystalNum = equipService.getCount(getCrystal(), isUseLimit, role);
        /**宝石*/
        int gemNum = equipService.getCount(getGemName(level), isUseLimit, role);

        if (crystalNum < size) {
            return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, getCrystal());
        }
        /**如果是预览炼化*/
        if (opType) {
            if (gemNum < 1) {
                return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, getGemName(level));
            }
        }

        if (level >= 70) {
            if (role.getMoney() < needCash(level, 0)) {
                return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, MONEY_NAME);
            }
        }

        return null;
    }

    @Override
    public int needCash(short level, int pos) {
        return 0;
    }

    @Override
    public String getUpdateTypeStr() {
        return null;
    }

    /**
     * 预览炼化需要的宝石名
     */
    private String getGemName(int level) {
        if (level < 80) {
            return "蓝松石";
        } else if (level < 110) {
            return "芙蓉石";
        } else {
            return "红宝石";
        }
    }

    @Override
    int getNotifyType() {
        return NOTIFY_EQUIP_REFINE_OK;
    }

}
